chore(FR-2814): patch relay-runtime to expose full @catch error details#7247
chore(FR-2814): patch relay-runtime to expose full @catch error details#7247yomybaby wants to merge 1 commit into
Conversation
Upstream Relay strips `message` (and never exposes `extensions`) from the per-field error objects surfaced via `@catch`, citing PII safety. This patches `RelayReader._asResult` to return the full GraphQL error object for `relay_field_payload.error` so components can read `message` / `extensions` directly instead of parsing wrapper text or routing through the global `relayFieldLogger` side-channel.
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has required the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
There was a problem hiding this comment.
Pull request overview
This PR introduces a pnpm patch for relay-runtime@20.1.1 to stop Relay’s @catch per-field error handling from stripping GraphQL error details, so WebUI components can access the full error object (e.g., message, extensions) directly from the errors array.
Changes:
- Add a pnpm patch that changes
RelayReader’s handling ofrelay_field_payload.errorto return the fullerror.errorobject. - Register the patch via
patchedDependenciesso it is applied consistently in developer installs and CI.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| react/patches/relay-runtime@20.1.1.patch | Modifies Relay runtime’s field error mapping to expose the complete GraphQL error object instead of a sanitized subset. |
| pnpm-workspace.yaml | Registers the new relay-runtime patch under patchedDependencies so pnpm applies it automatically. |

Resolves #7246(FR-2814)
Summary
relay-runtime@20.1.1so theerrorsarray exposed by@catchfields preserves the full GraphQL error object (message,extensions, etc.) instead of the upstream-stripped subset (path+severityonly).pnpm-workspace.yamlunderpatchedDependenciesso it applies automatically for all developers and CI; the patch file lives inreact/patches/next to the existing patches.case 'relay_field_payload.error':inRelayReader._asResultis changed to returnerror.errordirectly, with an inline comment explaining the deviation from upstream.Why
Relay 18+ deliberately strips
messagefrom the per-field error objects (and never exposesextensions) for PII safety. In our codebase this forces awkward workarounds — e.g.PrometheusQueryTemplatePreviewparses the GraphQL error wrapper string viaindexOfto recover backend messages. The official escape hatches (relayFieldLoggerglobal side-channel, schema-level error payloads) are either too coarse for component-level UX or require backend changes per call site. We accept the PII trade-off in exchange for a usable error UX in our internal admin tooling.Test plan
pnpm installre-applies the patch cleanly (verify a_patch_hash=directory undernode_modules/.pnpm/relay-runtime@20.1.1...).@catch, when the backend returns a field error, the resultingerrors[i]includesmessage(andextensionswhen present), in addition topath.bash scripts/verify.sh→=== ALL PASS ===.Notes
Result<T, unknown>for the error type, so consumers need to cast at the use site (e.g.errors[0] as { path: readonly (string|number)[]; message?: string; extensions?: Record<string, unknown> }). No type changes are required in this PR.indexOf-based message parsing inPrometheusQueryTemplatePreviewwith directerrors[0].messageaccess (separate PR / Jira issue).